package dblockcache;

import java.io.IOException;
import java.util.*;

import virtualdisk.Disk;
import virtualdisk.VirtualDisk;

import common.Constants;
import common.Constants.DiskOperationType;

public class Cache extends DBufferCache {

	HashMap<Integer, DBuffer> _bufferMap;
	VirtualDisk _disk;
	
	private volatile boolean inUse;

	public Cache(int cacheSize) {
		super(cacheSize);
		_cacheSize = Constants.BLOCK_SIZE * cacheSize;
		_bufferMap = new HashMap<Integer, DBuffer>();
	}

	/*
	 * Get buffer for block specified by blockID. The buffer is "held" until the
	 * caller releases it. A "held" buffer cannot be evicted: its block ID
	 * cannot change.
	 */
	@Override
	public DBuffer getBlock(int blockID) throws IllegalArgumentException,
			IOException {
		// if buffer is not in cache, then make from disk
		DBuffer dbuf = null;
		if (_bufferMap.containsKey(blockID)) {
			dbuf = _bufferMap.get(blockID);
		} else {
			dbuf = new Buffer();
			dbuf.setBlockID(blockID);
			dbuf.startFetch();
			// make sure block is valid before returning it
			if (!dbuf.checkValid()) {
				dbuf.waitValid();
			}
			_bufferMap.put(blockID, dbuf);
		}
		return dbuf;

		// include some kind of lock
	}

	/* Release the buffer so that others waiting on it can use it */
	@Override
	public void releaseBlock(DBuffer buf) {
		// release lock
	}

	@Override
	public void sync() {
		for (int key : _bufferMap.keySet()) {
			DBuffer dbuf = _bufferMap.get(key);
			if (!dbuf.checkClean()) { // block is dirty
				dbuf.startPush();
				// don't go to next block until this block is done
				dbuf.waitClean();
			}
		}
	}

}
